package com.nlecloud.bc.util;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Map;

/**
 * @author warrior
 * @description url指定页面转化为单个html文件，并截图
 */
@Slf4j
public class URL2SingletonHtml {

    /**
     * 网页编码
     */
    private static final String STR_ENCODING = "UTF-8";


    /**
     * 方法说明：执行下载操作<br>
     * 输入参数：strWeb 网页地址; strText 网页内容; strFilePath 保存路径<br>
     */
    public static HashMap<String, String> compile(String html) throws Exception {
        Document doc = Jsoup.parse(html);
        Elements imgElements = doc.select("img[src]");
        URL strImg = extractBaseURL(doc.select("img[src]"));
        HashMap<String, String> urlMap = extractAllImageElements(strImg, imgElements);
        return urlMap;
    }

    /**
     * 方法说明：下载文件操作<br>
     * 输入参数：url 文件路径<br>
     * 返回类型：byte[]<br>
     */
    private static byte[] downBinaryFile(String urlStr) throws IOException {
        int contentLength;
        URL url = new URL(urlStr);
        URLConnection conn = url.openConnection();
        conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.101 Safari/537.36");
        contentLength = conn.getContentLength();
        InputStream raw;
        if (contentLength > 0) {
            raw = conn.getInputStream();
            InputStream in = new BufferedInputStream(raw);
            byte[] data = new byte[contentLength];
            int bytesRead = 0;
            int offset = 0;
            while (offset < contentLength) {
                bytesRead = in.read(data, offset, data.length - offset);
                if (bytesRead == -1) {
                    break;
                }
                offset += bytesRead;
            }
            in.close();
            raw.close();
            return data;
        }
        return null;

    }

    /**
     * 方法说明：抽取基础URL地址<br>
     * 输入参数：nodes 网页标签集合<br>
     * 返回类型：URL<br>
     */
    private static URL extractBaseURL(Elements elements) throws MalformedURLException {
        if (elements == null)
            return null;
        URL url = null;
        for (Element element : elements) {
            String href = element.attr("href");
            if (href != null && href.length() > 0) {
                url = new URL(href);
                break;
            }
        }
        return url;
    }

    /**
     * 方法说明：抽取网页包含的图像链接<br>
     *
     * @param url      web页面的url
     * @param elements img的标签元素列表
     */
    private static HashMap<String, String> extractAllImageElements(URL url, Elements elements) throws Exception {
        HashMap<String, String> urlMap = new HashMap<>();
        for (Element e : elements) {
            String src = e.attr("src");
            if ((src.startsWith("http://") || src.startsWith("https://")) && (src.endsWith(".jpg") || src.endsWith(".jpeg") || src.endsWith(".png"))) {
                byte[] bs = downBinaryFile(src);
                urlMap.put(src, bs == null ? null : new Image(bs).getBase64(true));
            }
        }
        return urlMap;
    }

    /**
     * 把页面html的js、css路径出去，img路径替换为base64
     *
     * @param html 页面内容
     * @param linkMap 文件内部链接与文件内容的映射
     * @return 替换后的页面内容
     */
    public static String replaceHtml(String html,Map<String, String> linkMap) {
        if (StringUtils.isBlank(html)) {
            return html;
        }
        Document doc = Jsoup.parse(html);
        Elements imgElements = doc.select("img[src]");
        for (Element e : imgElements) {
            String href = e.attr("src");
            if (linkMap.containsKey(href)) {
                String text = linkMap.get(href);
                e.attr("data-src", href);
                if (text != null)
                    e.attr("src", linkMap.get(href));
            }
        }
        return doc.html();
    }

    public static void saveAsFileWriter(String content, String filePath) throws IOException {
        File file = new File(filePath);
        File path = file.getParentFile();
        FileUtils.forceMkdir(path);
        FileUtils.writeStringToFile(file, content, STR_ENCODING);
    }
}
